<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>

                    <h4>多重继承</h4>
                    <div class="x-wiki-info"><span>1006次阅读</span></div>
                    <hr style="border-top-color:#ccc" />
                    <div class="x-wiki-content x-content"><p>继承是面向对象编程的一个重要的方式，因为通过继承，子类就可以扩展父类的功能。</p>
<p>回忆一下<code>Animal</code>类层次的设计，假设我们要实现以下4种动物：</p>
<ul>
<li>Dog - 狗狗；</li>
<li>Bat - 蝙蝠；</li>
<li>Parrot - 鹦鹉；</li>
<li>Ostrich - 鸵鸟。</li>
</ul>
<p>如果按照哺乳动物和鸟类归类，我们可以设计出这样的类的层次：</p>
<p><img src="http://www.liaoxuefeng.com/files/attachments/0013946302979476f6c8274380449f6b1661232f3c87e27000/0" alt="animal-mb"></p>
<p>但是如果按照“能跑”和“能飞”来归类，我们就应该设计出这样的类的层次：</p>
<p><img src="http://www.liaoxuefeng.com/files/attachments/0013946303378967df13b07e0f64ed396560af4f6a98207000/0" alt="animal-rf"></p>
<p>如果要把上面的两种分类都包含进来，我们就得设计更多的层次：</p>
<ul>
<li>哺乳类：能跑的哺乳类，能飞的哺乳类；</li>
<li>鸟类：能跑的鸟类，能飞的鸟类。</li>
</ul>
<p>这么一来，类的层次就复杂了：</p>
<p><img src="http://www.liaoxuefeng.com/files/attachments/0013946304409926336fd4395ef4ce1809253a1d87dd2fe000/0" alt="animal-mb-rf"></p>
<p>如果要再增加“宠物类”和“非宠物类”，这么搞下去，类的数量会呈指数增长，很明显这样设计是不行的。</p>
<p>正确的做法是采用多重继承。首先，主要的类层次仍按照哺乳类和鸟类设计：</p>
<pre><code>class Animal(object):
    pass

# 大类:
class Mammal(Animal):
    pass

class Bird(Animal):
    pass

# 各种动物:
class Dog(Mammal):
    pass

class Bat(Mammal):
    pass

class Parrot(Bird):
    pass

class Ostrich(Bird):
    pass
</code></pre><p>现在，我们要给动物再加上<code>Runnable</code>和<code>Flyable</code>的功能，只需要先定义好<code>Runnable</code>和<code>Flyable</code>的类：</p>
<pre><code>class Runnable(object):
    def run(self):
        print(&#39;Running...&#39;)

class Flyable(object):
    def fly(self):
        print(&#39;Flying...&#39;)
</code></pre><p>对于需要<code>Runnable</code>功能的动物，就多继承一个<code>Runnable</code>，例如<code>Dog</code>：</p>
<pre><code>class Dog(Mammal, Runnable):
    pass
</code></pre><p>对于需要<code>Flyable</code>功能的动物，就多继承一个<code>Flyable</code>，例如<code>Bat</code>：</p>
<pre><code>class Bat(Mammal, Flyable):
    pass
</code></pre><p>通过多重继承，一个子类就可以同时获得多个父类的所有功能。</p>
<h3 id="mixin">Mixin</h3>
<p>在设计类的继承关系时，通常，主线都是单一继承下来的，例如，<code>Ostrich</code>继承自<code>Bird</code>。但是，如果需要“混入”额外的功能，通过多重继承就可以实现，比如，让<code>Ostrich</code>除了继承自<code>Bird</code>外，再同时继承<code>Runnable</code>。这种设计通常称之为Mixin。</p>
<p>为了更好地看出继承关系，我们把<code>Runnable</code>和<code>Flyable</code>改为<code>RunnableMixin</code>和<code>FlyableMixin</code>。类似的，你还可以定义出肉食动物<code>CarnivorousMixin</code>和植食动物<code>HerbivoresMixin</code>，让某个动物同时拥有好几个Mixin：</p>
<pre><code>class Dog(Mammal, RunnableMixin, CarnivorousMixin):
    pass
</code></pre><p>Mixin的目的就是给一个类增加多个功能，这样，在设计类的时候，我们优先考虑通过多重继承来组合多个Mixin的功能，而不是设计多层次的复杂的继承关系。</p>
<p>Python自带的很多库也使用了Mixin。举个例子，Python自带了<code>TCPServer</code>和<code>UDPServer</code>这两类网络服务，而要同时服务多个用户就必须使用多进程或多线程模型，这两种模型由<code>ForkingMixin</code>和<code>ThreadingMixin</code>提供。通过组合，我们就可以创造出合适的服务来。</p>
<p>比如，编写一个多进程模式的TCP服务，定义如下：</p>
<pre><code>class MyTCPServer(TCPServer, ForkingMixin):
    pass
</code></pre><p>编写一个多线程模式的UDP服务，定义如下：</p>
<pre><code>class MyUDPServer(UDPServer, ThreadingMixin):
    pass
</code></pre><p>如果你打算搞一个更先进的协程模型，可以编写一个<code>CoroutineMixin</code>：</p>
<pre><code>class MyTCPServer(TCPServer, CoroutineMixin):
    pass
</code></pre><p>这样一来，我们不需要复杂而庞大的继承链，只要选择组合不同的类的功能，就可以快速构造出所需的子类。</p>
<h3 id="-">小结</h3>
<p>由于Python允许使用多重继承，因此，Mixin就是一种常见的设计。</p>
<p>只允许单一继承的语言（如Java）不能使用Mixin的设计。</p>
</div>

                    <hr style="border-top-color:#ccc" />

                    